/*  ----------------------------------------------------------------------------
 *  Arello Mobile
 *  Fast 3d Engine
 *  ----------------------------------------------------------------------------
 * Except where otherwise noted, this work is licensed under
 * http://creativecommons.org/licenses/by/3.0
 */

#include <Net/Session.h>
#include <logs/Log.h>
#include <safe_new.h>
#include <vector>

namespace liba
{
namespace net
{


Session::Session(RWSocket * rw_socket)
:	rw_socket( rw_socket ),
	msg_required_len( 0 ),
	size_read_len( 0 )
{}

Session::~Session()
{
	delete rw_socket;
}

bool Session::send_message(const std::string & buf)
{
	if( buf.empty() )
		return true;
	int size = buf.size();
	return 
		rw_socket->write( &size, 4 ) == 4 
		&& rw_socket->write( buf.data(), buf.size() ) == buf.size();
}

const std::string& Session::get_message()
{
	if( size_read_len < 4 )
	{
		size_read_len += rw_socket->read( &size_place + size_read_len, 4 - size_read_len );
		msg_required_len = (size_place[3] << 24) + (size_place[2] << 16) + (size_place[1] << 8) + size_place[0];
		if( size_read_len == 4 )
		{
			msg.resize( msg_required_len );
			size_read_msg_len = 0;
		}
	}
	if( size_read_len < 4 )
		return std::string();
	std::vector<char> v( msg.size() );
	size_read_msg_len += rw_socket->read( &(v.front()) + size_read_msg_len, msg_required_len - size_read_msg_len );
	if( size_read_msg_len != msg_required_len )
		return std::string();
	size_read_len = 0;
	msg.assign( v.begin(), v.end() );
	return msg;
}

bool Session::is_valid()const
{
	return rw_socket->is_valid();
}

} // namespace net
} // namespace liba

